from hashlib import sha1
from re import search
from threading import Thread
from tkinter import StringVar, Tk
from tkinter.constants import DISABLED, END, EW, NORMAL, NSEW, E, N, S, W
from tkinter.ttk import Button, Entry, Frame, Label, Progressbar
from urllib.request import HTTPError, Request, urlopen

HOSTSDIR = r'C:\Windows\System32\drivers\etc\hosts'
HOSTURL = r'https://raw.githubusercontent.com/googlehosts/hosts/master/hosts-files/hosts'

resText = ''
oldHash = ''

def getDate(text):
    res = search(r'Last updated: ([0-9\-]+)', text)
    if res:
        return res.group(1)
    return False

def getGitSha1(text):
    return sha1(f'blob {len(text)}\0{text}'.encode('utf-8')).hexdigest()

def getLocalInfo():
    global oldHash
    with open(HOSTSDIR) as f: 
        oldFile = f.read()
    date = getDate(oldFile)
    if date:
        oldHash = getGitSha1(oldFile)
        localVersion.set(f'{date} {oldHash[:7]}')
        
    else:
        localVersion.set('未知')
        

def getRemoteInfoThread():
    global resText
    if not oldHash:
        getLocalInfo()
    req = Request(HOSTURL, headers={'If-None-Match': f'"{oldHash}"'})
    try:
        res = urlopen(req)
        resText = res.read().decode('utf-8')
        resHash = res.getheader('ETag').strip('"')
        remoteVersion.set(f'{getDate(resText)} {resHash[:7]}')
        infoBar.set('需要更新, 请点更新按钮更新')
    except HTTPError as err:
        if err.code == 304:
            remoteVersion.set(localVersion.get())
            infoBar.set('已是最新版, 无需更新')
        else:
            infoBar.set(f'请求失败，错误码{err.code}')
    progressBar.stop()

def getRemoteInfo():
    infoBar.set('正在获取最新版...')
    progressBar.start()
    t = Thread(target=getRemoteInfoThread)
    t.start()

def modifyFile():
    if not resText:
        getLocalInfo()
        getRemoteInfo()
    if resText:
        with open(HOSTSDIR, 'w') as f:
            f.write(resText)
            infoBar.set('已更新至最新版')

root = Tk()
root.title('GetHosts')
root.resizable(width=False, height=False)
f = Frame(root, padding=(6,3,6,3))
f.grid()

localVersion = StringVar()
remoteVersion = StringVar()
infoBar = StringVar()
infoBar.set('GetHosts-0.1.5-20170106')

Label(f, text='本地版本：').grid(row=1, column=1)
Entry(f, textvariable=localVersion, state='readonly').grid(row=1, column=2, padx=5)
Button(f, text='刷新', command=getLocalInfo).grid(row=1, column=3, pady=3)
Label(f, text='远程版本：').grid(row=2, column=1)
Entry(f, textvariable=remoteVersion, state='readonly').grid(row=2, column=2, padx=5)
Button(f, text='刷新', command=getRemoteInfo).grid(row=2, column=3, pady=3)
progressBar = Progressbar(f, mode='indeterminate')
progressBar.grid(row=3, column=1, columnspan=3, sticky=EW, pady=3)
Label(f, textvariable=infoBar).grid(row=4, column=1, columnspan=2, sticky=EW)
Button(f, text='更新', command=modifyFile).grid(row=4, column=3, pady=3)

getLocalInfo()
root.mainloop()
